package com.yqg.protection.netty.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.yqg.protection.entity.*;
import com.yqg.protection.service.*;
import com.yqg.protection.utils.ByteUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;

@Service
@Slf4j
public class KeAn4040Service extends ProtocolService {

    @Autowired
    private IFireUnitStateDataService fireUnitStateDataService;
    @Autowired
    private IWarnRecordService warnRecordService;
    @Autowired
    private IEquipmentUnitService equipmentUnitService;
    @Autowired
    private IEquipmentInputStoreService equipmentInputStoreService;
    @Autowired
    IFireSysStateDataService fireSysStateDataService;

    // 时间格式化
    public String formatTime(String time) {
        return "20" + String.format("%02d", Long.parseLong(time.substring(10, 12), 16)) + "-" +
                String.format("%02d", Long.parseLong(time.substring(8, 10), 16)) + "-" +
                String.format("%02d", Long.parseLong(time.substring(6, 8), 16)) + " " +
                String.format("%02d", Long.parseLong(time.substring(4, 6), 16)) + ":" +
                String.format("%02d", Long.parseLong(time.substring(2, 4), 16)) + ":" +
                String.format("%02d", Long.parseLong(time.substring(0, 2), 16));
    }

    // 解析数据单元
    public void analyzeDataUnits(String flow, String sendTime, String raw, String src) {
        String rawType = ByteUtil.HexToNum(raw.substring(0, 2));
        log.info("rawType:" + rawType);
        String rawTotal = ByteUtil.HexToNum(raw.substring(2, 4));
        log.info("rawTotal:" + rawTotal);
        raw = raw.substring(4);
        String explanation;
        //2上传建筑消防设施部件运行状态
        if (rawType.equals("2")) {
            ArrayList<FireUnitStateData> fireUnitStateDatas = new ArrayList<>();
            ArrayList<WarnRecord> warnRecords = new ArrayList<>();
            ArrayList<EquipmentUnit> equipmentUnits = new ArrayList<>();
            EquipmentInputStore equipmentInputStore = getEquipmentInputStore(src);
            for (int i = 0; i < raw.length(); ) {
                String sysType = raw.substring(i, i + 2);
                log.info("sysType:" + sysType);
                String sysAddr = raw.substring(i + 2, i + 4);
                log.info("sysAddr:" + sysAddr);
                String unitType = raw.substring(i + 4, i + 6);
                log.info("unitType:" + unitType);
                String unitAddr = raw.substring(i + 12, i + 14) + raw.substring(i + 10, i + 12) + raw.substring(i + 8, i + 10) + raw.substring(i + 6, i + 8);
                log.info("unitAddr:" + unitAddr);
                String decimalString = String.format("%09d", Long.parseLong(unitAddr, 16));
                log.info("unitAddrNum:" + decimalString);
                String unitState = raw.substring(i + 16, i + 18) + raw.substring(i + 14, i + 16);
                log.info("unitStateNum:" + ByteUtil.HexToNum(unitState));
                String unitExp = raw.substring(18, 80);
                log.info("unitExp:" + ByteUtil.HexToNum(unitExp));
                String unitTime = "20" + String.format("%02d", Long.parseLong(raw.substring(i + 90, i + 92), 16)) + "-" + String.format("%02d", Long.parseLong(raw.substring(i + 88, i + 90), 16)) + "-" + String.format("%02d", Long.parseLong(raw.substring(i + 86, i + 88), 16)) + " " + String.format("%02d", Long.parseLong(raw.substring(i + 84, i + 86), 16)) + ":" + String.format("%02d", Long.parseLong(raw.substring(i + 82, i + 84), 16)) + ":" + String.format("%02d", Long.parseLong(raw.substring(i + 80, i + 82), 16));
                log.info("unitTime:" + unitTime);
                i = i + 92;
                if (decimalString.equals("001006000")) {
                    continue;
                }
                FireUnitStateData fireUnitStateData = new FireUnitStateData();
                fireUnitStateData.setEquipmentId(src);
                fireUnitStateData.setFlow(flow);
                fireUnitStateData.setSysType(sysType);
                fireUnitStateData.setSysAddr(sysAddr);
                fireUnitStateData.setUnitType(unitType);
                fireUnitStateData.setUnitAddr(decimalString);
                byte[] array = ByteUtil.getBooleanArray(ByteUtil.hexStringToByteArray(unitState));
                for (int j = 0; j < array.length; j++) {
                    if (array[j] == 1) {
                        unitState = String.valueOf(15 - j);
                    }
                }
                LambdaQueryWrapper<EquipmentUnit> equipmentUnitQueryWrapper = new LambdaQueryWrapper<>();
                equipmentUnitQueryWrapper.eq(EquipmentUnit::getEquipmentInputStoreId, equipmentInputStore.getId());
                equipmentUnitQueryWrapper.eq(EquipmentUnit::getPartModel, decimalString);
                equipmentUnitQueryWrapper.eq(EquipmentUnit::getIsDelete, 0);
                EquipmentUnit equipmentUnit = equipmentUnitService.getOne(equipmentUnitQueryWrapper);
                equipmentUnit.setWarnStateNum(unitState);
                equipmentUnits.add(equipmentUnit);
                fireUnitStateData.setUnitState(unitState);
                fireUnitStateData.setUnitDesc(unitExp);
                fireUnitStateData.setOccurTime(unitTime);
                fireUnitStateData.setSendTime(sendTime);
                fireUnitStateDatas.add(fireUnitStateData);
                WarnRecord warnRecord = new WarnRecord();
                warnRecord.setEquipmentInputStoreId(equipmentInputStore.getId());
                warnRecord.setPartModel(decimalString);
                warnRecord.setWarnStateNum(unitState);
                warnRecord.setWarnTypeNum(Integer.valueOf(unitType));
                warnRecord.setIsDeal(0);
                warnRecord.setIsMisinformation("0");
                warnRecord.setTeleNotification("1");
                warnRecord.setFaultReport("0");
                warnRecord.setFieldSurvey("0");
                warnRecord.setEliminHidDang("0");
                warnRecord.setCreateTime(LocalDateTime.now());
                warnRecord.setWarnTime(unitTime);
                warnRecord.setWarnAddr(equipmentUnit.getInstallSite());
                warnRecord.setIsDelete(0);
                warnRecords.add(warnRecord);
            }
            fireUnitStateDataService.saveBatch(fireUnitStateDatas);
            warnRecordService.saveBatch(warnRecords);
            equipmentUnitService.saveOrUpdateBatch(equipmentUnits);
            explanation = "上传建筑消防设施部件运行状态";
            //报警推送
            sendWarnNotice(equipmentInputStore, warnRecords);
        } else if (rawType.equals("28")) {
            //28上传用户信息装置系统时间(心跳)
            sendTime = "20" + String.format("%02d", Long.parseLong(raw.substring(10, 12), 16)) + "-" + String.format("%02d", Long.parseLong(raw.substring(8, 10), 16)) + "-" + String.format("%02d", Long.parseLong(raw.substring(6, 8), 16)) + " " + String.format("%02d", Long.parseLong(raw.substring(4, 6), 16)) + ":" + String.format("%02d", Long.parseLong(raw.substring(2, 4), 16)) + ":" + String.format("%02d", Long.parseLong(raw.substring(0, 2), 16));
            explanation = "上传用户信息装置系统时间";
        } else if (rawType.equals("1")) {
            //1建筑消防设施系统状态
            ArrayList<FireSysStateData> fireSysStateDatas = new ArrayList<>();
            String sysState = "";
            for (int i = 0; i < raw.length(); ) {
                String sysType = raw.substring(i, i + 2);
                String sysAddr = raw.substring(i + 2, i + 4);
                sysState = raw.substring(i + 6, i + 8) + raw.substring(i + 4, i + 6);
                String sysTime = "20" + String.format("%02d", Long.parseLong(raw.substring(18, 20), 16)) + "-" + String.format("%02d", Long.parseLong(raw.substring(16, 18), 16)) + "-" + String.format("%02d", Long.parseLong(raw.substring(14, 16), 16)) + " " + String.format("%02d", Long.parseLong(raw.substring(12, 14), 16)) + ":" + String.format("%02d", Long.parseLong(raw.substring(10, 12), 16)) + ":" + String.format("%02d", Long.parseLong(raw.substring(8, 10), 16));
                i = i + 20;
                FireSysStateData fireSysStateData = new FireSysStateData();
                fireSysStateData.setFlow(flow);
                fireSysStateData.setEquipmentId(src);
                fireSysStateData.setSysType(sysType);
                fireSysStateData.setSysAddr(sysAddr);
                fireSysStateData.setSysState(sysState);
                fireSysStateData.setSysTime(sysTime);
                fireSysStateData.setSendTime(sendTime);
                fireSysStateDatas.add(fireSysStateData);
            }
            fireSysStateDataService.saveBatch(fireSysStateDatas);
            byte[] array = ByteUtil.getBooleanArray(ByteUtil.hexStringToByteArray(sysState));
            for (int i = 0; i < array.length; i++) {
                if (array[i] == 1) {
                    EquipmentInputStore equipmentInputStore = getEquipmentInputStore(src);
                    equipmentInputStore.setState(String.valueOf(15 - i));
                    equipmentInputStore.setUpdateTime(sendTime);
                    equipmentInputStoreService.updateById(equipmentInputStore);
                }
            }
            explanation = "上传建筑消防设施系统状态";
        } else {
            explanation = "上传数据解析失败";
        }
        //记录设备数据上传内容
        saveFireSysData(src, explanation, sendTime);
        //更新设备数据上传时间(用于记录设备是否在线)
        updateTemporaryData(src, sendTime);
    }
}
